/*
 * @Author       : Xu Xiaokang
 * @Email        : XudaKang_up@qq.com
 * @Date         : 2022-05-05 11:11:22
 * @LastEditors  : Xu Xiaokang
 * @LastEditTime : 2022-11-09 11:17:24
 * @Filename     :
 * @Description  :
*/

/*
! 模块功能: 在uart收发模块外层再封装一层FIFO，包含发送FIFO与接收FIFO，以解决波特率误差导致接收位偏移的问题
* 思路:
  1.
*/

module uartRTUseFIFO
#(
  parameter CLK_FREQ_MHZ = 100,
  parameter BAUD         = 115200, // 波特率, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
  parameter DATA_BITS    = 8,      // 数据位宽度, 可选5, 6, 7, 8
  parameter PARITY       = "NONE", // 校验 "NONE", "ODD", "EVEN", "MARK", "SPACE"
  parameter STOP_BITS    = 1       // 停止位宽度可选1, 1.5, 2
)(
  // 发送数据 FWFT FIFO
  input  wire         tx_cclk_fwft_fifo_8wxxd_empty,
  input  wire [7 : 0] tx_cclk_fwft_fifo_8wxxd_dout,
  output wire         tx_cclk_fwft_fifo_8wxxd_rd_en,

  // 接收数据 FWFT FIFO
  input  wire         rx_cclk_fwft_fifo_8wxxd_full,
  output wire [7 : 0] rx_cclk_fwft_fifo_8wxxd_din,
  output wire         rx_cclk_fwft_fifo_8wxxd_wr_en,

  output wire rdata_error, // 接收错误

  output wire uart_tx,
  input  wire uart_rx,

  input  wire clk,
  input  wire rstn
);


//++ 实例化串口收发模块 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
wire [DATA_BITS - 1 : 0]  rdata;       // 接收到的数据
wire                      rdata_valid; // 指示接收数据有效; 高电平有效

wire [DATA_BITS - 1 : 0]  tdata;       // 要发送的数据
wire                      tdata_valid; // 指示发送数据有效; 此信号上升沿有效
wire                      uart_tx_ready; // 发送准备就绪

uartTx #(
  .CLK_FREQ_MHZ    (CLK_FREQ_MHZ   ),
  .BAUD            (BAUD           ),
  .DATA_BITS       (DATA_BITS      ),
  .PARITY          (PARITY         ),
  .STOP_BITS       (STOP_BITS      )
) uartTx_dut       (
  .tdata           (tdata          ),
  .tdata_valid     (tdata_valid    ),
  .uart_tx_ready   (uart_tx_ready  ),
  .uart_tx         (uart_tx        ),
  .clk             (clk            ),
  .rstn            (rstn           )
);


uartRx #(
  .CLK_FREQ_MHZ    (CLK_FREQ_MHZ   ),
  .BAUD            (BAUD           ),
  .DATA_BITS       (DATA_BITS      ),
  .PARITY          (PARITY         ),
  .STOP_BITS       (STOP_BITS      )
) uartRx_dut       (
  .rdata           (rdata          ),
  .rdata_valid     (rdata_valid    ),
  .rdata_error     (rdata_error    ),
  .uart_rx         (uart_rx        ),
  .clk             (clk            ),
  .rstn            (rstn           )
);
//-- 实例化串口收发模块 ------------------------------------------------------------


//++ 发送数据FIFO接口连接 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
assign tdata = tx_cclk_fwft_fifo_8wxxd_dout[DATA_BITS - 1 : 0];

reg tx_cclk_fwft_fifo_8wxxd_rd_en_temp;
always @(posedge clk) begin
  tx_cclk_fwft_fifo_8wxxd_rd_en_temp <= uart_tx_ready && tdata_valid;
end

assign tx_cclk_fwft_fifo_8wxxd_rd_en = ~tx_cclk_fwft_fifo_8wxxd_empty && tx_cclk_fwft_fifo_8wxxd_rd_en_temp;

assign tdata_valid = ~tx_cclk_fwft_fifo_8wxxd_empty;
//-- 发送数据FIFO接口连接 ------------------------------------------------------------


//++ 接收数据FIFO接口连接 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
reg rdata_valid_r1;
always @(posedge clk) begin
  rdata_valid_r1 <= rdata_valid;
end

assign rdata_valid_pedge = rdata_valid && ~rdata_valid_r1;

assign rx_cclk_fwft_fifo_8wxxd_wr_en = ~rx_cclk_fwft_fifo_8wxxd_full && rdata_valid_pedge;
assign rx_cclk_fwft_fifo_8wxxd_din = rdata;
//-- 接收数据FIFO接口连接 ------------------------------------------------------------


endmodule